package com.writing.service.impl;

import com.writing.entity.Chapter;
import com.writing.entity.Novel;
import com.writing.service.ChapterService;
import com.writing.service.ChapterSplitService;
import com.writing.service.NovelService;
import com.writing.util.EncodingDetector;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 章节拆分服务实现类
 */
@Slf4j
@Service
public class ChapterSplitServiceImpl implements ChapterSplitService {

    private final ChapterService chapterService;
    private final NovelService novelService;

    @Autowired
    public ChapterSplitServiceImpl(ChapterService chapterService, @Lazy NovelService novelService) {
        this.chapterService = chapterService;
        this.novelService = novelService;
    }
    
    // 章节标题识别模式
    private static final List<Pattern> CHAPTER_PATTERNS;
    
    static {
        CHAPTER_PATTERNS = new ArrayList<>();
        CHAPTER_PATTERNS.add(Pattern.compile("^第[一二三四五六七八九十百千万\\d]+[章节]\\s*(.*)$", Pattern.MULTILINE));
        CHAPTER_PATTERNS.add(Pattern.compile("^Chapter\\s+(\\d+|[IVXLCDM]+)\\s*[:\\-]?\\s*(.*)$", Pattern.MULTILINE | Pattern.CASE_INSENSITIVE));
        CHAPTER_PATTERNS.add(Pattern.compile("^(\\d+)[\\uff0e\\u3001\\s]+(.*)$", Pattern.MULTILINE)); // 使用Unicode转义
        CHAPTER_PATTERNS.add(Pattern.compile("^[一二三四五六七八九十百千万]+[\\uff0e\\u3001\\s]+(.*)$", Pattern.MULTILINE));
        CHAPTER_PATTERNS.add(Pattern.compile("^第[一二三四五六七八九十百千万\\d]+卷\\s+第[一二三四五六七八九十百千万\\d]+[章节]\\s*(.*)$", Pattern.MULTILINE));
        CHAPTER_PATTERNS.add(Pattern.compile("^[章节]\\s*[一二三四五六七八九十百千万\\d]+\\s*[:\\-]?\\s*(.*)$", Pattern.MULTILINE));
        CHAPTER_PATTERNS.add(Pattern.compile("^第(\\d+)回\\s*(.*)$", Pattern.MULTILINE));
    }

    // 章节长度限制常量
    private static final int MIN_CHAPTER_LENGTH = 500;   // 最小章节长度（字符数）
    private static final int MAX_CHAPTER_LENGTH = 15000; // 最大章节长度（字符数）
    private static final int IDEAL_CHAPTER_LENGTH = 3000; // 理想章节长度（字符数）
    private static final int MIN_WORD_COUNT = 200;       // 最小字数（去除空白后）
    private static final int MAX_WORD_COUNT = 8000;      // 最大字数（去除空白后）
    private static final double MERGE_THRESHOLD = 0.3;   // 合并阈值：章节长度小于理想长度的30%时考虑合并
    private static final double SPLIT_THRESHOLD = 2.5;   // 拆分阈值：章节长度大于理想长度的2.5倍时考虑拆分
    
    @Override
    public ChapterSplitResult splitChapters(Novel novel, MultipartFile file, String encoding) {
        try {
            log.info("开始拆分小说章节: novelId={}, encoding={}", novel.getId(), encoding);
            
            // 读取文件内容
            String content = readFileContent(file, encoding);
            if (content == null || content.trim().isEmpty()) {
                return new ChapterSplitResult(false, "文件内容为空", 0, 0);
            }
            
            // 预处理文本
            content = preprocessText(content);
            
            // 尝试拆分章节
            List<ChapterInfo> chapters = extractChapters(content);
            
            if (chapters.isEmpty()) {
                // 如果没有识别到章节，创建单个章节
                chapters.add(new ChapterInfo(1, novel.getTitle(), content, 0, content.length()));
            }
            
            // 保存章节到数据库
            int totalWords = 0;
            for (int i = 0; i < chapters.size(); i++) {
                ChapterInfo chapterInfo = chapters.get(i);
                
                Chapter chapter = new Chapter();
                chapter.setNovelId(novel.getId());
                chapter.setChapterOrder(i + 1);
                chapter.setTitle(chapterInfo.getTitle());
                chapter.setContent(chapterInfo.getContent());
                chapter.setWordCount(chapterInfo.getWordCount());
                
                chapterService.createChapter(chapter);
                totalWords += chapterInfo.getWordCount();
            }
            
            // 更新小说统计信息
            novel.setChapterCount(chapters.size());
            novel.setWordCount(totalWords);
            novel.setProcessingStatus("completed");
            novelService.updateById(novel);
            
            log.info("章节拆分完成: novelId={}, chapterCount={}, totalWords={}", 
                    novel.getId(), chapters.size(), totalWords);
            
            return new ChapterSplitResult(true, "拆分成功", chapters.size(), totalWords);
            
        } catch (Exception e) {
            log.error("章节拆分失败: novelId={}", novel.getId(), e);
            
            // 更新处理状态为失败
            novel.setProcessingStatus("failed");
            novelService.updateById(novel);
            
            return new ChapterSplitResult(false, "拆分失败: " + e.getMessage(), 0, 0);
        }
    }
    
    @Override
    @Async
    public void splitChaptersAsync(Long novelId, String content) {
        try {
            Novel novel = novelService.getById(novelId);
            if (novel == null) {
                log.error("小说不存在: novelId={}", novelId);
                return;
            }

            // 设置处理状态
            novel.setProcessingStatus("processing");
            novelService.updateById(novel);

            // 执行拆分
            splitChaptersFromContent(novel, content);

        } catch (Exception e) {
            log.error("异步章节拆分失败: novelId={}", novelId, e);

            // 更新处理状态为失败
            Novel novel = novelService.getById(novelId);
            if (novel != null) {
                novel.setProcessingStatus("failed");
                novelService.updateById(novel);
            }
        }
    }

    /**
     * 从文本内容拆分章节
     */
    private ChapterSplitResult splitChaptersFromContent(Novel novel, String content) {
        try {
            log.info("开始拆分小说章节: novelId={}", novel.getId());

            if (content == null || content.trim().isEmpty()) {
                return new ChapterSplitResult(false, "文件内容为空", 0, 0);
            }

            // 预处理文本
            content = preprocessText(content);

            // 尝试拆分章节
            List<ChapterInfo> chapters = extractChapters(content);

            if (chapters.isEmpty()) {
                // 如果没有识别到章节，创建单个章节
                chapters.add(new ChapterInfo(1, novel.getTitle(), content, 0, content.length()));
            }

            // 保存章节到数据库
            int totalWords = 0;
            for (int i = 0; i < chapters.size(); i++) {
                ChapterInfo chapterInfo = chapters.get(i);

                Chapter chapter = new Chapter();
                chapter.setNovelId(novel.getId());
                chapter.setChapterOrder(i + 1);
                chapter.setTitle(chapterInfo.getTitle());
                chapter.setContent(chapterInfo.getContent());
                chapter.setWordCount(chapterInfo.getWordCount());

                chapterService.createChapter(chapter);
                totalWords += chapterInfo.getWordCount();
            }

            // 更新小说统计信息
            novel.setChapterCount(chapters.size());
            novel.setWordCount(totalWords);
            novel.setProcessingStatus("completed");
            novelService.updateById(novel);

            log.info("章节拆分完成: novelId={}, chapterCount={}, totalWords={}",
                    novel.getId(), chapters.size(), totalWords);

            return new ChapterSplitResult(true, "拆分成功", chapters.size(), totalWords);

        } catch (Exception e) {
            log.error("章节拆分失败: novelId={}", novel.getId(), e);

            // 更新处理状态为失败
            novel.setProcessingStatus("failed");
            novelService.updateById(novel);

            return new ChapterSplitResult(false, "拆分失败: " + e.getMessage(), 0, 0);
        }
    }

    /**
     * 读取文件内容 - 增强编码检测
     */
    private String readFileContent(MultipartFile file, String encoding) throws Exception {
        // 首先读取文件的所有字节
        byte[] bytes = file.getBytes();

        // 如果文件为空，直接返回
        if (bytes.length == 0) {
            return "";
        }

        String detectedEncoding;

        // 如果用户选择自动检测或者指定的编码无效，使用智能检测
        if ("auto".equals(encoding) || !EncodingDetector.isEncodingSupported(encoding)) {
            detectedEncoding = EncodingDetector.detectEncoding(bytes);
            log.info("自动检测到文件编码: {}", detectedEncoding);
        } else {
            // 验证用户指定的编码是否正确
            try {
                String testContent = new String(bytes, encoding);
                if (!containsGarbledText(testContent)) {
                    detectedEncoding = encoding;
                    log.info("使用用户指定的编码: {}", encoding);
                } else {
                    log.warn("用户指定的编码 {} 产生乱码，使用自动检测", encoding);
                    detectedEncoding = EncodingDetector.detectEncoding(bytes);
                }
            } catch (Exception e) {
                log.warn("用户指定的编码 {} 无效，使用自动检测: {}", encoding, e.getMessage());
                detectedEncoding = EncodingDetector.detectEncoding(bytes);
            }
        }

        try {
            // 使用检测到的编码读取文件
            String content = new String(bytes, detectedEncoding);
            log.info("成功使用编码 {} 读取文件，内容长度: {}", detectedEncoding, content.length());
            return content;
        } catch (Exception e) {
            // 最后的备用方案
            log.error("使用检测到的编码 {} 读取文件失败，使用UTF-8强制读取: {}", detectedEncoding, e.getMessage());
            return new String(bytes, "UTF-8");
        }
    }



    /**
     * 检查文本是否包含乱码
     */
    private boolean containsGarbledText(String content) {
        if (content == null || content.isEmpty()) {
            return false;
        }

        // 检查是否包含大量的替换字符（�）
        long replacementCharCount = content.chars().filter(ch -> ch == 0xFFFD).count();
        if (replacementCharCount > content.length() * 0.1) { // 如果替换字符超过10%
            return true;
        }

        // 检查是否包含过多的控制字符
        long controlCharCount = content.chars()
                .filter(ch -> Character.isISOControl(ch) && ch != '\n' && ch != '\r' && ch != '\t')
                .count();
        if (controlCharCount > content.length() * 0.05) { // 如果控制字符超过5%
            return true;
        }

        // 检查是否有合理的文本内容（包含常见的中文或英文字符）
        long validCharCount = content.chars()
                .filter(ch -> Character.isLetterOrDigit(ch) ||
                             Character.UnicodeBlock.of(ch) == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS ||
                             Character.UnicodeBlock.of(ch) == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A ||
                             Character.UnicodeBlock.of(ch) == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B)
                .count();

        // 如果有效字符少于30%，可能是乱码
        return validCharCount < content.length() * 0.3;
    }
    
    /**
     * 预处理文本
     */
    private String preprocessText(String text) {
        // 统一换行符
        text = text.replaceAll("\\r\\n", "\n").replaceAll("\\r", "\n");
        
        // 移除过多的空行
        text = text.replaceAll("\\n{3,}", "\n\n");
        
        // 移除行首行尾空白
        String[] lines = text.split("\n");
        StringBuilder processed = new StringBuilder();
        for (String line : lines) {
            processed.append(line.trim()).append("\n");
        }
        
        return processed.toString();
    }
    
    /**
     * 提取章节
     */
    private List<ChapterInfo> extractChapters(String content) {
        List<ChapterInfo> chapters = new ArrayList<>();

        // 尝试每个模式
        for (Pattern pattern : CHAPTER_PATTERNS) {
            List<ChapterMatch> matches = findChapterMatches(content, pattern);
            if (matches.size() >= 2) { // 至少需要2个匹配才认为是有效模式
                chapters = extractChaptersFromMatches(content, matches);
                if (!chapters.isEmpty()) {
                    log.info("使用模式成功拆分章节: pattern={}, chapterCount={}",
                            pattern.pattern(), chapters.size());
                    break;
                }
            }
        }

        // 如果所有模式都失败，尝试基于长度的启发式拆分
        if (chapters.isEmpty()) {
            chapters = splitByLength(content);
        }

        // 优化章节长度和质量
        chapters = optimizeChapters(chapters, content);

        return chapters;
    }
    
    /**
     * 查找章节匹配
     */
    private List<ChapterMatch> findChapterMatches(String content, Pattern pattern) {
        List<ChapterMatch> matches = new ArrayList<>();
        Matcher matcher = pattern.matcher(content);
        
        while (matcher.find()) {
            String title = matcher.group(0).trim();
            if (matcher.groupCount() > 0 && matcher.group(1) != null) {
                String titlePart = matcher.group(1).trim();
                if (!titlePart.isEmpty()) {
                    title = titlePart;
                }
            }
            
            matches.add(new ChapterMatch(matcher.start(), title));
        }
        
        return matches;
    }
    
    /**
     * 从匹配结果中提取章节
     */
    private List<ChapterInfo> extractChaptersFromMatches(String content, List<ChapterMatch> matches) {
        List<ChapterInfo> chapters = new ArrayList<>();
        
        for (int i = 0; i < matches.size(); i++) {
            ChapterMatch match = matches.get(i);
            int startPos = match.getPosition();
            int endPos = (i + 1 < matches.size()) ? matches.get(i + 1).getPosition() : content.length();
            
            String chapterContent = content.substring(startPos, endPos).trim();
            int wordCount = calculateWordCount(chapterContent);
            
            chapters.add(new ChapterInfo(i + 1, match.getTitle(), chapterContent, startPos, endPos, wordCount));
        }
        
        return chapters;
    }
    
    /**
     * 基于长度的启发式拆分
     */
    private List<ChapterInfo> splitByLength(String content) {
        List<ChapterInfo> chapters = new ArrayList<>();
        
        int avgChapterLength = 3000; // 假设平均章节长度
        int estimatedChapters = Math.max(1, content.length() / avgChapterLength);
        
        if (estimatedChapters == 1) {
            chapters.add(new ChapterInfo(1, "全文", content, 0, content.length()));
            return chapters;
        }
        
        int currentPos = 0;
        for (int i = 0; i < estimatedChapters && currentPos < content.length(); i++) {
            int targetPos = Math.min(currentPos + avgChapterLength, content.length());
            int endPos = findBestBreakPoint(content, targetPos);
            
            if (i == estimatedChapters - 1) {
                endPos = content.length();
            }
            
            String chapterContent = content.substring(currentPos, endPos).trim();
            int wordCount = calculateWordCount(chapterContent);
            
            chapters.add(new ChapterInfo(i + 1, "第" + (i + 1) + "章", chapterContent, currentPos, endPos, wordCount));
            currentPos = endPos;
        }
        
        return chapters;
    }
    
    /**
     * 寻找最佳断点 - 改进版
     */
    private int findBestBreakPoint(String content, int targetPos) {
        int searchRange = 300; // 增加搜索范围
        int start = Math.max(0, targetPos - searchRange);
        int end = Math.min(content.length(), targetPos + searchRange);

        int bestPos = targetPos;
        int bestPriority = -1;
        String bestType = "默认";

        // 1. 寻找段落边界（双换行）- 最高优先级
        int pos = start;
        while ((pos = content.indexOf("\n\n", pos)) != -1 && pos < end) {
            int distance = Math.abs(pos - targetPos);
            int priority = 100 - distance / 10; // 距离越近优先级越高
            if (priority > bestPriority) {
                bestPos = pos + 2;
                bestPriority = priority;
                bestType = "段落边界";
            }
            pos += 2;
        }

        // 2. 寻找句子结束（句号、感叹号、问号）
        String[] sentenceEnders = {"\u3002", "\uff01", "\uff1f", ".", "!", "?"}; // 使用Unicode转义
        for (String ender : sentenceEnders) {
            pos = start;
            while ((pos = content.indexOf(ender, pos)) != -1 && pos < end) {
                // 检查后面是否跟着换行或空格，这样的断点更自然
                boolean followedBySpace = pos + ender.length() < content.length() &&
                                        (content.charAt(pos + ender.length()) == '\n' ||
                                         content.charAt(pos + ender.length()) == ' ');

                int distance = Math.abs(pos - targetPos);
                int priority = (followedBySpace ? 80 : 60) - distance / 15;
                if (priority > bestPriority) {
                    bestPos = pos + ender.length();
                    bestPriority = priority;
                    bestType = "句子结束";
                }
                pos += ender.length();
            }
        }

        // 3. 寻找对话结束（引号后的换行）
        String[] quotes = {"\u201d", "\"", "'"}; // 使用Unicode转义避免编译错误
        for (String quote : quotes) {
            pos = start;
            while ((pos = content.indexOf(quote, pos)) != -1 && pos < end) {
                if (pos + quote.length() < content.length() &&
                    content.charAt(pos + quote.length()) == '\n') {
                    int distance = Math.abs(pos - targetPos);
                    int priority = 70 - distance / 12;
                    if (priority > bestPriority) {
                        bestPos = pos + quote.length();
                        bestPriority = priority;
                        bestType = "对话结束";
                    }
                }
                pos += quote.length();
            }
        }

        // 4. 寻找普通换行
        pos = start;
        while ((pos = content.indexOf("\n", pos)) != -1 && pos < end) {
            // 避免重复添加双换行的情况
            if (pos == 0 || content.charAt(pos - 1) != '\n') {
                int distance = Math.abs(pos - targetPos);
                int priority = 40 - distance / 20;
                if (priority > bestPriority) {
                    bestPos = pos + 1;
                    bestPriority = priority;
                    bestType = "换行";
                }
            }
            pos += 1;
        }

        // 5. 寻找逗号后的空格
        String[] commas = {"\uff0c", ",", "\uff1b", ";"}; // 使用Unicode转义
        for (String comma : commas) {
            pos = start;
            while ((pos = content.indexOf(comma, pos)) != -1 && pos < end) {
                if (pos + comma.length() < content.length() &&
                    content.charAt(pos + comma.length()) == ' ') {
                    int distance = Math.abs(pos - targetPos);
                    int priority = 30 - distance / 25;
                    if (priority > bestPriority) {
                        bestPos = pos + comma.length();
                        bestPriority = priority;
                        bestType = "逗号";
                    }
                }
                pos += comma.length();
            }
        }

        if (bestPriority > 0) {
            log.debug("选择断点: 位置={}, 类型={}, 优先级={}", bestPos, bestType, bestPriority);
        }

        return bestPos;
    }
    
    /**
     * 计算字数
     */
    private int calculateWordCount(String content) {
        if (content == null || content.trim().isEmpty()) {
            return 0;
        }
        
        // 移除空白字符，计算实际字数
        String cleanContent = content.replaceAll("\\s+", "");
        return cleanContent.length();
    }
    
    /**
     * 章节匹配信息
     */
    private static class ChapterMatch {
        private final int position;
        private final String title;
        
        public ChapterMatch(int position, String title) {
            this.position = position;
            this.title = title;
        }
        
        public int getPosition() {
            return position;
        }
        
        public String getTitle() {
            return title;
        }
    }
    
    /**
     * 章节信息
     */
    private static class ChapterInfo {
        private final int number;
        private final String title;
        private final String content;
        private final int startPos;
        private final int endPos;
        private final int wordCount;
        
        public ChapterInfo(int number, String title, String content, int startPos, int endPos) {
            this(number, title, content, startPos, endPos, content.replaceAll("\\s+", "").length());
        }
        
        public ChapterInfo(int number, String title, String content, int startPos, int endPos, int wordCount) {
            this.number = number;
            this.title = title;
            this.content = content;
            this.startPos = startPos;
            this.endPos = endPos;
            this.wordCount = wordCount;
        }
        
        public int getNumber() {
            return number;
        }
        
        public String getTitle() {
            return title;
        }
        
        public String getContent() {
            return content;
        }
        
        public int getStartPos() {
            return startPos;
        }
        
        public int getEndPos() {
            return endPos;
        }
        
        public int getWordCount() {
            return wordCount;
        }
    }

    /**
     * 优化章节长度和质量
     */
    private List<ChapterInfo> optimizeChapters(List<ChapterInfo> originalChapters, String fullContent) {
        if (originalChapters.isEmpty()) {
            return originalChapters;
        }

        log.info("开始优化章节，原始章节数: {}", originalChapters.size());

        // 第一步：合并过短的章节
        List<ChapterInfo> mergedChapters = mergeShortChapters(originalChapters);
        log.info("合并后章节数: {}", mergedChapters.size());

        // 第二步：拆分过长的章节
        List<ChapterInfo> splitChapters = splitLongChapters(mergedChapters);
        log.info("拆分后章节数: {}", splitChapters.size());

        // 第三步：重新编号和验证
        List<ChapterInfo> finalChapters = renumberAndValidateChapters(splitChapters);
        log.info("最终章节数: {}", finalChapters.size());

        // 输出章节长度统计
        logChapterStatistics(finalChapters);

        return finalChapters;
    }

    /**
     * 合并过短的章节
     */
    private List<ChapterInfo> mergeShortChapters(List<ChapterInfo> chapters) {
        List<ChapterInfo> result = new ArrayList<>();

        for (int i = 0; i < chapters.size(); i++) {
            ChapterInfo current = chapters.get(i);

            // 检查当前章节是否过短
            if (isChapterTooShort(current)) {
                // 尝试与下一个章节合并
                if (i + 1 < chapters.size()) {
                    ChapterInfo next = chapters.get(i + 1);
                    ChapterInfo merged = mergeChapters(current, next);

                    log.info("合并过短章节: {} + {} -> {}",
                            current.getTitle(), next.getTitle(), merged.getTitle());

                    result.add(merged);
                    i++; // 跳过下一个章节，因为已经合并了
                } else if (!result.isEmpty()) {
                    // 如果是最后一个章节且过短，与前一个章节合并
                    ChapterInfo previous = result.remove(result.size() - 1);
                    ChapterInfo merged = mergeChapters(previous, current);

                    log.info("合并最后的过短章节: {} + {} -> {}",
                            previous.getTitle(), current.getTitle(), merged.getTitle());

                    result.add(merged);
                } else {
                    // 如果只有一个章节且过短，保留它
                    result.add(current);
                }
            } else {
                result.add(current);
            }
        }

        return result;
    }

    /**
     * 拆分过长的章节
     */
    private List<ChapterInfo> splitLongChapters(List<ChapterInfo> chapters) {
        List<ChapterInfo> result = new ArrayList<>();

        for (ChapterInfo chapter : chapters) {
            if (isChapterTooLong(chapter)) {
                List<ChapterInfo> splitChapters = splitChapter(chapter);
                log.info("拆分过长章节: {} -> {} 个子章节", chapter.getTitle(), splitChapters.size());
                result.addAll(splitChapters);
            } else {
                result.add(chapter);
            }
        }

        return result;
    }

    /**
     * 检查章节是否过短
     */
    private boolean isChapterTooShort(ChapterInfo chapter) {
        return chapter.getContent().length() < MIN_CHAPTER_LENGTH ||
               chapter.getWordCount() < MIN_WORD_COUNT ||
               chapter.getContent().length() < IDEAL_CHAPTER_LENGTH * MERGE_THRESHOLD;
    }

    /**
     * 检查章节是否过长
     */
    private boolean isChapterTooLong(ChapterInfo chapter) {
        return chapter.getContent().length() > MAX_CHAPTER_LENGTH ||
               chapter.getWordCount() > MAX_WORD_COUNT ||
               chapter.getContent().length() > IDEAL_CHAPTER_LENGTH * SPLIT_THRESHOLD;
    }

    /**
     * 合并两个章节
     */
    private ChapterInfo mergeChapters(ChapterInfo first, ChapterInfo second) {
        String mergedContent = first.getContent() + "\n\n" + second.getContent();
        String mergedTitle = first.getTitle();

        // 如果第一个章节的标题是默认生成的，尝试使用更好的标题
        if (mergedTitle.matches("第\\d+章") && !second.getTitle().matches("第\\d+章")) {
            mergedTitle = second.getTitle();
        } else if (!mergedTitle.matches("第\\d+章") && !second.getTitle().matches("第\\d+章")) {
            mergedTitle = first.getTitle() + " & " + second.getTitle();
        }

        return new ChapterInfo(
            first.getNumber(),
            mergedTitle,
            mergedContent,
            first.getStartPos(),
            second.getEndPos(),
            calculateWordCount(mergedContent)
        );
    }

    /**
     * 拆分单个章节
     */
    private List<ChapterInfo> splitChapter(ChapterInfo chapter) {
        List<ChapterInfo> result = new ArrayList<>();
        String content = chapter.getContent();

        // 计算需要拆分成几个部分
        int targetParts = (int) Math.ceil((double) content.length() / IDEAL_CHAPTER_LENGTH);
        targetParts = Math.max(2, Math.min(targetParts, 5)); // 最多拆分成5个部分

        int partLength = content.length() / targetParts;
        int currentPos = 0;

        for (int i = 0; i < targetParts; i++) {
            int endPos;
            if (i == targetParts - 1) {
                // 最后一部分包含剩余所有内容
                endPos = content.length();
            } else {
                // 寻找合适的断点
                int targetEndPos = currentPos + partLength;
                endPos = findBestBreakPoint(content, targetEndPos);

                // 确保不会产生过短的片段
                if (endPos - currentPos < MIN_CHAPTER_LENGTH && i < targetParts - 1) {
                    endPos = Math.min(currentPos + MIN_CHAPTER_LENGTH, content.length());
                }
            }

            String partContent = content.substring(currentPos, endPos).trim();
            if (partContent.length() > 0) {
                String partTitle = generateSplitChapterTitle(chapter.getTitle(), i + 1, targetParts);

                result.add(new ChapterInfo(
                    chapter.getNumber() * 100 + i + 1, // 临时编号，后续会重新编号
                    partTitle,
                    partContent,
                    chapter.getStartPos() + currentPos,
                    chapter.getStartPos() + endPos,
                    calculateWordCount(partContent)
                ));
            }

            currentPos = endPos;
        }

        return result;
    }

    /**
     * 生成拆分章节的标题
     */
    private String generateSplitChapterTitle(String originalTitle, int partNumber, int totalParts) {
        if (originalTitle.matches("第\\d+章.*")) {
            return originalTitle + "\uff08" + partNumber + "/" + totalParts + "\uff09"; // 使用Unicode转义
        } else if (originalTitle.equals("全文")) {
            return "第" + partNumber + "部分";
        } else {
            return originalTitle + "\uff08" + partNumber + "\uff09"; // 使用Unicode转义
        }
    }

    /**
     * 重新编号和验证章节
     */
    private List<ChapterInfo> renumberAndValidateChapters(List<ChapterInfo> chapters) {
        List<ChapterInfo> result = new ArrayList<>();

        for (int i = 0; i < chapters.size(); i++) {
            ChapterInfo chapter = chapters.get(i);

            // 重新编号
            ChapterInfo renumbered = new ChapterInfo(
                i + 1,
                chapter.getTitle(),
                chapter.getContent(),
                chapter.getStartPos(),
                chapter.getEndPos(),
                chapter.getWordCount()
            );

            result.add(renumbered);
        }

        return result;
    }

    /**
     * 输出章节长度统计
     */
    private void logChapterStatistics(List<ChapterInfo> chapters) {
        if (chapters.isEmpty()) {
            return;
        }

        int totalWords = chapters.stream().mapToInt(ChapterInfo::getWordCount).sum();
        int minWords = chapters.stream().mapToInt(ChapterInfo::getWordCount).min().orElse(0);
        int maxWords = chapters.stream().mapToInt(ChapterInfo::getWordCount).max().orElse(0);
        double avgWords = (double) totalWords / chapters.size();

        int minLength = chapters.stream().mapToInt(ch -> ch.getContent().length()).min().orElse(0);
        int maxLength = chapters.stream().mapToInt(ch -> ch.getContent().length()).max().orElse(0);
        double avgLength = chapters.stream().mapToInt(ch -> ch.getContent().length()).average().orElse(0);

        log.info("章节统计信息:");
        log.info("  总章节数: {}", chapters.size());
        log.info("  总字数: {}", totalWords);
        log.info("  字数范围: {} - {} (平均: {:.0f})", minWords, maxWords, avgWords);
        log.info("  长度范围: {} - {} (平均: {:.0f})", minLength, maxLength, avgLength);

        // 检查是否还有不合理的章节
        long shortChapters = chapters.stream().filter(this::isChapterTooShort).count();
        long longChapters = chapters.stream().filter(this::isChapterTooLong).count();

        if (shortChapters > 0) {
            log.warn("  仍有 {} 个过短章节", shortChapters);
        }
        if (longChapters > 0) {
            log.warn("  仍有 {} 个过长章节", longChapters);
        }
    }
}
